package khmt.lvtn.dhbk.model.process;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Hashtable;

import khmt.lvtn.dhbk.model.CommonModel;
import khmt.lvtn.dhbk.model.EntityModel;
import khmt.lvtn.dhbk.model.SentimentModel;


public class MainProcess {
	private GetNeedWord getNeedWord = new GetNeedWord();

	public String[] listSubSentence(String sen) {
		return sen.split("[.,!?;-]+");
	}

	public String[] listPunctuation(String sen) {
		return sen.split("[^.?,;!-]+");
	}

	// Get Adjective
	public ArrayList<SentimentModel> processGetAdj(String sen) {
		ArrayList<SentimentModel> adj = new ArrayList<SentimentModel>();
		String[] sentence = listSubSentence(sen);
		String[] punctua = listPunctuation(sen);
		int prev = 0;
		for (int i = 0; i < sentence.length; i++) {
			if (i == 0) {
				prev += sentence[i].length();
			} else {
				prev += (sentence[i].length() + punctua[i].length());
			}
			ArrayList<SentimentModel> tmp = getNeedWord.getAdj(sentence[i]);
			if (tmp.size() > 0) {
				for (int j = 0; j < tmp.size(); j++) {
					if (i == 0) {
						adj.add(new SentimentModel(tmp.get(j)
								.getWordSentiment(), tmp.get(j).getLocation(),
								tmp.get(j).getScore()));
					} else {

						adj.add(new SentimentModel(tmp.get(j)
								.getWordSentiment(), tmp.get(j).getLocation()
								+ prev - sentence[i].length(), tmp.get(j)
								.getScore()));
					}
				}
			}
		}
		return adj;
	}

	// Get Verb
	public ArrayList<SentimentModel> processGetVerb(String sen) {
		ArrayList<SentimentModel> verb = new ArrayList<SentimentModel>();
		String[] sentence = listSubSentence(sen);
		String[] punctua = listPunctuation(sen);
		int prev = 0;
		for (int i = 0; i < sentence.length; i++) {
			if (i == 0) {
				prev += sentence[i].length();
			} else {
				prev += (sentence[i].length() + punctua[i].length());
			}
			ArrayList<SentimentModel> tmp = getNeedWord.getVerb(sentence[i]);
			if (tmp.size() > 0) {
				for (int j = 0; j < tmp.size(); j++) {
					if (i == 0) {
						verb.add(new SentimentModel(tmp.get(j)
								.getWordSentiment(), tmp.get(j).getLocation(),
								tmp.get(j).getScore()));
					} else {
						verb.add(new SentimentModel(tmp.get(j)
								.getWordSentiment(), tmp.get(j).getLocation()
								+ prev - sentence[i].length(), tmp.get(j)
								.getScore()));
					}
				}
			}
		}
		return verb;
	}

	// Get Auxiliary
	public ArrayList<SentimentModel> processGetAuxiliary(String sen) {
		ArrayList<SentimentModel> aux = new ArrayList<SentimentModel>();
		String[] sentence = listSubSentence(sen);
		String[] punctua = listPunctuation(sen);
		int prev = 0;
		for (int i = 0; i < sentence.length; i++) {
			if (i == 0) {
				prev += sentence[i].length();
			} else {
				prev += (sentence[i].length() + punctua[i].length());
			}
			// ArrayList<CommonModel> tmp =
			// getNeedWord.getAuxiliary(sentence[i]);
			ArrayList<SentimentModel> tmp = getNeedWord
					.getAuxiliary(sentence[i]);
			if (tmp.size() > 0) {
				for (int j = 0; j < tmp.size(); j++) {
					if (i == 0) {
						aux.add(new SentimentModel(tmp.get(j)
								.getWordSentiment(), tmp.get(j).getLocation(),
								tmp.get(j).getScore()));
					} else {
						aux.add(new SentimentModel(tmp.get(j)
								.getWordSentiment(), tmp.get(j).getLocation()
								+ prev - sentence[i].length(), tmp.get(j)
								.getScore()));
					}
				}
			}
		}
		return aux;
	}

	// Get Negative
	public ArrayList<CommonModel> processGetNegative(String sen) {
		ArrayList<CommonModel> neg = new ArrayList<CommonModel>();
		String[] sentence = listSubSentence(sen);
		String[] punctua = listPunctuation(sen);
		int prev = 0;
		for (int i = 0; i < sentence.length; i++) {
			if (i == 0) {
				prev += sentence[i].length();
			} else {
				prev += (sentence[i].length() + punctua[i].length());
			}
			ArrayList<CommonModel> tmp = getNeedWord.getNegative(sentence[i]);
			if (tmp.size() > 0) {
				for (int j = 0; j < tmp.size(); j++) {
					if (i == 0) {
						neg.add(new CommonModel(tmp.get(j).getWordCommon(), tmp
								.get(j).getLocation()));
					} else {
						neg.add(new CommonModel(tmp.get(j).getWordCommon(), tmp
								.get(j).getLocation()
								+ prev
								- sentence[i].length()));
					}
				}
			}
		}
		return neg;
	}

	// Get Entity
	public ArrayList<CommonModel> processGetEntity(String sen) {
		ArrayList<CommonModel> entity = new ArrayList<CommonModel>();
		String[] sentence = listSubSentence(sen);
		String[] punctua = listPunctuation(sen);
		int prev = 0;
		for (int i = 0; i < sentence.length; i++) {
			if (i == 0) {
				prev += sentence[i].length();
			} else {
				prev += (sentence[i].length() + punctua[i].length());
			}
			ArrayList<CommonModel> tmp = getNeedWord.getEntity(sentence[i]);
			if (tmp.size() > 0) {
				for (int j = 0; j < tmp.size(); j++) {
					if (i == 0) {
						entity.add(new CommonModel(tmp.get(j).getWordCommon(),
								tmp.get(j).getLocation()));
					} else {
						entity.add(new CommonModel(tmp.get(j).getWordCommon(),
								tmp.get(j).getLocation() + prev
										- sentence[i].length()));
					}
				}
			}
		}
		return entity;
	}

	// Get Property
	public ArrayList<CommonModel> processGetProperty(String sen) {
		ArrayList<CommonModel> prop = new ArrayList<CommonModel>();
		String[] sentence = listSubSentence(sen);
		String[] punctua = listPunctuation(sen);
		int prev = 0;
		for (int i = 0; i < sentence.length; i++) {
			if (i == 0) {
				prev += sentence[i].length();
			} else {
				prev += (sentence[i].length() + punctua[i].length());
			}
			ArrayList<CommonModel> tmp = getNeedWord.getProperty(sentence[i]);
			if (tmp.size() > 0) {
				for (int j = 0; j < tmp.size(); j++) {
					if (i == 0) {
						prop.add(new CommonModel(tmp.get(j).getWordCommon(),
								tmp.get(j).getLocation()));
					} else {
						prop.add(new CommonModel(tmp.get(j).getWordCommon(),
								tmp.get(j).getLocation() + prev
										- sentence[i].length()));
					}
				}
			}
		}
		return prop;
	}

	// Get Entity and Property
	public ArrayList<CommonModel> processGetEntityAndProperty(String sen) {
		EntityModel list = new EntityModel();
		list = processGetListEntityAndProperty(sen);
		ArrayList<CommonModel> model = (ArrayList<CommonModel>) list
				.getSuperEntity();
		ArrayList<CommonModel> model1 = (ArrayList<CommonModel>) list
				.getProperty();
		for (int i = 0; i < model1.size(); i++) {
			model.add(new CommonModel(model1.get(i).getWordCommon(), model1
					.get(i).getLocation()));
		}
		Collections.sort(model, new Comparator<CommonModel>() {

			@Override
			public int compare(CommonModel o1, CommonModel o2) {
				// TODO Auto-generated method stub
				return o1.getLocation() - o2.getLocation();
			}
		});
		return model;
	}

	// get Entity
	public EntityModel processGetListEntityAndProperty(String sen) {
		return (new EntityModel(processGetEntity(sen), processGetProperty(sen)));
	}

	// Get Pronoun
	public ArrayList<CommonModel> processGetPronoun(String sen) {
		ArrayList<CommonModel> pronoun = new ArrayList<CommonModel>();
		String[] sentence = listSubSentence(sen);
		String[] punctua = listPunctuation(sen);
		int prev = 0;
		for (int i = 0; i < sentence.length; i++) {
			if (i == 0) {
				prev += sentence[i].length();
			} else {
				prev += (sentence[i].length() + punctua[i].length());
			}
			ArrayList<CommonModel> tmp = getNeedWord.getPronoun(sentence[i]);
			if (tmp.size() > 0) {
				for (int j = 0; j < tmp.size(); j++) {
					if (i == 0) {
						pronoun.add(new CommonModel(tmp.get(j).getWordCommon(),
								tmp.get(j).getLocation()));
					} else {
						pronoun.add(new CommonModel(tmp.get(j).getWordCommon(),
								tmp.get(j).getLocation() + prev
										- sentence[i].length()));
					}
				}
			}
		}
		return pronoun;
	}

	// isQuestion
	public boolean isQuestion(String sen) {
		sen = sen.replaceAll("[.?,:!]", "").toLowerCase();
		String[] oneWord = getNeedWord.getOneWord(sen);
		String file = "data/question.txt";
		boolean flag1 = false;
		boolean flag2 = false;
		for (int i = 0; i < oneWord.length; i++) {
			flag1 = getNeedWord.compareWord(oneWord[i], file);
			if (i < oneWord.length - 1) {
				flag2 = getNeedWord.compareWord(
						oneWord[i].concat(" ").concat(oneWord[i + 1]), file);
			}

			if (flag1 || flag2) {
				return true;
			}
		}
		return false;
	}

	// Get Nhung word
	public ArrayList<Integer> processGetNhungWord(String sen) {
		ArrayList<Integer> listInt = new ArrayList<Integer>();
		String[] sentence = listSubSentence(sen);
		String[] punctua = listPunctuation(sen);
		int prev = 0;
		for (int i = 0; i < sentence.length; i++) {
			if (i == 0) {
				prev += sentence[i].length();
			} else {
				prev += (sentence[i].length() + punctua[i].length());
			}
			ArrayList<Integer> tmp = getNeedWord.getNhungWord(sentence[i]);
			if (tmp.size() > 0) {
				for (int j = 0; j < tmp.size(); j++) {
					if (i == 0) {
						listInt.add(tmp.get(j));
					} else {
						listInt.add(tmp.get(j) + prev - sentence[i].length());
					}
				}
			}
		}
		return listInt;
	}

	// calculator Precision
	public String calPrecision(int tp, int tn, int tpn, int sp, int sn, int spn) {
		double precision;
		precision = (double) tp / (tp + Math.abs(sp - tp)) * 100;
		DecimalFormat df = new DecimalFormat("0.00");
		df.setRoundingMode(RoundingMode.UP);
		return df.format(precision) + "%";
	}

	// calculator Recall
	public String calRecall(int tp, int tn, int tpn, int sp, int sn, int spn) {
		double recall;
		recall = (double) tp / (tp + Math.abs(sn - tn)) * 100;
		DecimalFormat df = new DecimalFormat("0.00");
		df.setRoundingMode(RoundingMode.UP);
		return df.format(recall) + "%";
	}

	public Hashtable<String, ArrayList<String>> getProductOfCompany(
			ArrayList<String> entiList) throws IOException {
		if (entiList.size() == 0) {
			return null;
		}

		Hashtable<String, ArrayList<String>> result = new Hashtable<String, ArrayList<String>>();

		Hashtable<String, ArrayList<String>> sameEntity = theSameEntities(entiList);
		Enumeration<String> vd2 = sameEntity.keys();
		while (vd2.hasMoreElements()) {
			String str = vd2.nextElement();

			String file = "ontology/WordSameClass.txt";
			FileReader fr = new FileReader(file);
			BufferedReader br = new BufferedReader(fr);
			String line = null;

			// get data in file ontology/WordSameClass
			while ((line = br.readLine()) != null) {
				String[] arrLine = line.split("[;:]");
				boolean flag = false;
				for (String string : arrLine) {
					if (str.equals(string)) {
						result.put(arrLine[0], sameEntity.get(str));
						flag = true;
						break;
					}
				}
				if (flag) {
					break;
				}
			}
			br.close();
			fr.close();

		}
		return result;
	}

	public Hashtable<String, ArrayList<String>> theSameEntities(
			ArrayList<String> entiList) throws IOException {
		if (entiList.size() == 0) {
			return null;
		}

		String file = "ontology/WordSameClass.txt";
		FileReader fr = new FileReader(file);
		BufferedReader br = new BufferedReader(fr);
		String line = null;
		Hashtable<Integer, ArrayList<String>> listFile = new Hashtable<Integer, ArrayList<String>>();
		Hashtable<String, ArrayList<String>> result = new Hashtable<String, ArrayList<String>>();

		ArrayList<String> list = new ArrayList<String>();
		for (int i = 0; i < entiList.size(); i++) {
			list.add(entiList.get(i));
		}

		// get data in file ontology/WordSameClass
		int dem = 0;
		while ((line = br.readLine()) != null) {
			ArrayList<String> listEachLine = new ArrayList<String>();
			String[] arrLine = line.split("[;:]");

			for (String string : arrLine) {
				listEachLine.add(string);
			}
			listEachLine.remove(0);
			listFile.put(dem, listEachLine);
			dem++;
		}
		br.close();
		fr.close();

		// process get same class list
		while (list.size() != 0) {
			String st = list.get(0);
			ArrayList<String> tempo = isListValid(st, listFile);
			if (tempo != null) {
				ArrayList<String> tempo1 = new ArrayList<String>();
				tempo1.add(st);
				list.remove(0);

				for (int i = 0; i < list.size(); i++) {
					for (int j = 0; j < tempo.size(); j++) {
						if (list.get(i).equals(tempo.get(j))) {
							tempo1.add(list.get(i));
							list.remove(i);
							i--;
							break;
						}
					}
				}

				result.put(tempo1.get(0), tempo1);
			}
		}
		return result;
	}

	private ArrayList<String> isListValid(String st,
			Hashtable<Integer, ArrayList<String>> hash) {
		for (int i = 0; i < hash.size(); i++) {
			for (int j = 0; j < hash.get(i).size(); j++) {
				if (st.equals(hash.get(i).get(j))) {
					// hash.get(i).add(st);
					return hash.get(i);
				}
			}
		}
		return null;
	}
	
	public PR getPR(String file1, String file2) {
		PR calPR = new PR();
		float pPositive = 0, rPositive = 0;
		float pNeutral = 0, rNeutral = 0;
		float pNegative = 0, rNegative = 0;
		int count = 0;
		try {
			FileReader frHu = new FileReader(file1);
			BufferedReader brHu = new BufferedReader(frHu);
			FileReader frSys = new FileReader(file2);
			BufferedReader brSys = new BufferedReader(frSys);
			String lnHu, lnSys;
			// lap tung dong
			while ((lnHu = brHu.readLine()) != null) {
				lnSys = brSys.readLine();
				String[] tmpHu = lnHu.split(";");
				String[] tmpSys = lnSys.split(";");
				// lay p [0] tach p
				String[] lnPHu = tmpHu[0].split("p:");
				String[] lnPSys = tmpSys[0].split("p:");

				// tach p

				if (lnPHu.length > 1) {
					if (lnPSys.length > 1) {
						String[] listHu = lnPHu[1].split(",");
						String[] listSys = lnPSys[1].split(",");
						int flag = 0;
						for (int i = 0; i < listSys.length; i++) {
							for (int j = 0; j < listHu.length; j++) {
								listHu[j] = listHu[j].replaceAll(" ", "")
										.toLowerCase();
								listSys[i] = listSys[i].replaceAll(" ", "")
										.toLowerCase();
								if (listSys[i].equals(listHu[j])) {
									flag++;
								}
							}
						}
						pPositive += (float) flag / listSys.length * 100.0;
						rPositive += (float) flag / listHu.length * 100.0;
					} else {
						pPositive += 0;
						rPositive += 0;
					}

				} else {
					if (lnPSys.length > 1) {
						pPositive += 0;
						rPositive += 0;
					} else {
						pPositive += 100.0;
						rPositive += 100.0;
					}
				}

				// lay n [1] tach n
				String[] lnNeHu = tmpHu[1].split("n:");
				String[] lnNeSys = tmpSys[1].split("n:");

				// tach n

				if (lnNeHu.length > 1) {
					if (lnNeSys.length > 1) {
						String[] listHu = lnNeHu[1].split(",");
						String[] listSys = lnNeSys[1].split(",");
						int flag = 0;
						for (int i = 0; i < listSys.length; i++) {
							for (int j = 0; j < listHu.length; j++) {
								listHu[j] = listHu[j].replaceAll(" ", "")
										.toLowerCase();
								listSys[i] = listSys[i].replaceAll(" ", "")
										.toLowerCase();
								if (listSys[i].equals(listHu[j])) {
									flag++;
								}
							}
						}
						pNegative += (float) flag / listSys.length * 100.0;
						rNegative += (float) flag / listHu.length * 100.0;
					} else {
						pNegative += 0;
						rNegative += 0;
					}

				} else {
					if (lnNeSys.length > 1) {
						pNegative += 0;
						rNegative += 0;
					} else {
						pNegative += 100.0;
						rNegative += 100.0;
					}
				}

				// lay pn [1] tach pn
				String[] lnNeutralHu = tmpHu[2].split("pn:");
				String[] lnNeutralSys = tmpSys[2].split("pn:");

				// tach pn

				if (lnNeutralHu.length > 1) {
					if (lnNeutralSys.length > 1) {
						String[] listHu = lnNeutralHu[1].split(",");
						String[] listSys = lnNeutralSys[1].split(",");
						int flag = 0;
						for (int i = 0; i < listSys.length; i++) {
							for (int j = 0; j < listHu.length; j++) {
								listHu[j] = listHu[j].replaceAll(" ", "")
										.toLowerCase();
								listSys[i] = listSys[i].replaceAll(" ", "")
										.toLowerCase();
								if (listSys[i].equals(listHu[j])) {
									flag++;
								}
							}
						}
						pNeutral += (float) flag / listSys.length * 100.0;
						rNeutral += (float) flag / listHu.length * 100.0;
					} else {
						pNeutral += 0;
						rNeutral += 0;
					}

				} else {
					if (lnNeutralSys.length > 1) {
						pNeutral += 0;
						rNeutral += 0;
					} else {
						pNeutral += 100.0;
						rNeutral += 100.0;
					}
				}
				count++;
			}
			frHu.close();
			frSys.close();
			calPR.setP((float) ((float) (pPositive / count)
					+ (float) (pNegative / count) + (float) (pNeutral / count)) / 3);
			calPR.setR((float) ((float) (rPositive / count)
                    + (float) (rNegative / count) + (float) (rNeutral / count)) / 3);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("Exception" + e);
		}

		return calPR;
	}

}
